//
//  UILabel+Lego.swift
//  SwiftTest_Example
//
//  Created by 马克吐温 on 2019/6/21.
//  Copyright © 2019 CocoaPods. All rights reserved.
//

import Foundation
import UIKit
import YYText
import SwiftyAttributes

public typealias moreActionClick = ((_ isMoreBTAction: Bool) -> Void)

public extension YYLabel {
    struct lineSpaceKey {
        static let key = UnsafeRawPointer(bitPattern: "lineSpaceKey".hashValue)
    }

    var lineSpace: CGFloat? {
        set {
            objc_setAssociatedObject(self, YYLabel.lineSpaceKey.key!, newValue, .OBJC_ASSOCIATION_COPY)
        }

        get {
            return objc_getAssociatedObject(self, YYLabel.lineSpaceKey.key!) as? CGFloat
        }
    }

    struct moreBTRuntimeKey {
        static let key = UnsafeRawPointer(bitPattern: "moreBTRuntimeKey".hashValue)
    }

    var moreBTTitle: String? {
        set {
            objc_setAssociatedObject(self, YYLabel.moreBTRuntimeKey.key!, newValue, .OBJC_ASSOCIATION_COPY)
        }

        get {
            return objc_getAssociatedObject(self, YYLabel.moreBTRuntimeKey.key!) as? String
        }
    }

    struct packupBTRuntimeKey {
        static let key = UnsafeRawPointer(bitPattern: "packupBTRuntimeKey".hashValue)
    }

    var packupBTTitle: String? {
        set {
            objc_setAssociatedObject(self, YYLabel.packupBTRuntimeKey.key!, newValue, .OBJC_ASSOCIATION_COPY)
        }

        get {
            return objc_getAssociatedObject(self, YYLabel.packupBTRuntimeKey.key!) as? String
        }
    }

    struct moreButtonTitleColorKey {
        static let key = UnsafeRawPointer(bitPattern: "moreButtonTitleColorKey".hashValue)
    }

    var moreButtonTitleColor: UIColor? {
        set {
            objc_setAssociatedObject(self, YYLabel.moreButtonTitleColorKey.key!, newValue, .OBJC_ASSOCIATION_COPY)
        }

        get {
            return objc_getAssociatedObject(self, YYLabel.moreButtonTitleColorKey.key!) as? UIColor
        }
    }

    struct zoomHeightKey {
        static let key = UnsafeRawPointer(bitPattern: "zoomHeightKey".hashValue)
    }

    var zoomHeight: CGFloat? {
        set {
            objc_setAssociatedObject(self, YYLabel.zoomHeightKey.key!, newValue, .OBJC_ASSOCIATION_COPY)
        }

        get {
            return objc_getAssociatedObject(self, YYLabel.zoomHeightKey.key!) as? CGFloat
        }
    }

    struct moreActionKey {
        static let key = UnsafeRawPointer(bitPattern: "moreActionKey".hashValue)
    }

    var actionClick: moreActionClick? {
        set {
            objc_setAssociatedObject(self, YYLabel.moreActionKey.key!, newValue, .OBJC_ASSOCIATION_COPY)
        }

        get {
            return objc_getAssociatedObject(self, YYLabel.moreActionKey.key!) as? moreActionClick
        }
    }

    // 增加增多按钮
    func addMoreButtonToLabel() {
        guard text != nil || attributedText != nil else {
            return
        }
        
        let attText =  attributedText ?? NSAttributedString(string: text!, attributes: [NSAttributedString.Key.font: font!])

        let attributed: NSMutableAttributedString = NSMutableAttributedString(attributedString: attText)

        attributed.yy_lineSpacing = lineSpace ?? 4

        attributedText = attributed

        let moreStr = moreBTTitle ?? "更多"

        let contentText = NSMutableAttributedString(string: moreStr)

        let range = contentText.string.range(of: moreStr)

        contentText.addAttributes([NSAttributedString.Key.font: font!, NSAttributedString.Key.foregroundColor: moreButtonTitleColor ?? UIColor.blue], range: contentText.string.nsRange(from: range!))

        let textHighlight = YYTextHighlight()

        contentText.yy_setTextHighlight(textHighlight, range: contentText.string.nsRange(from: range!))

        textHighlight.tapAction = { [weak self] (_: UIView, _: NSAttributedString, _: NSRange, _: CGRect) -> Void in
            self?.addPackupButtonToLabel()
            self?.sizeToFit()
            self?.actionClick!(true)
        }

        let seemore = YYLabel()

        seemore.attributedText = contentText

        seemore.sizeToFit()

        self.truncationToken = NSMutableAttributedString.yy_attachmentString(withContent: seemore, contentMode: UIView.ContentMode.center, attachmentSize: seemore.frame.size, alignTo: UIFont.systemFont(ofSize: font.pointSize - 5), alignment: .center)
    }

    // 增加收回按钮
    func addPackupButtonToLabel() {
        self.truncationToken = nil
        let packupStr = packupBTTitle ?? "收回"
        truncationToken = nil
        if attributedText != nil || text != nil {
            var str = attributedText ?? NSAttributedString(string: text!, attributes: [NSAttributedString.Key.font: font!])
            
//            let preEnd = moreBTTitle ?? "更多"
            
            let endRange = NSRange(location: str.length-packupStr.count, length: packupStr.count)
            
            let endString = str.attributedSubstring(from: endRange)
            
            if endString.string == packupStr {
                str = str.attributedSubstring(from: NSRange(location: 0, length: str.length - packupStr.count))
            }
            
            self.attributedText = str
        }

        let contentText = NSMutableAttributedString(attributedString: attributedText ?? NSAttributedString())

        let packupAttributedStr = packupStr.withTextColor(moreButtonTitleColor ?? .blue).withFont(font!)
        
        contentText.append(packupAttributedStr)

        contentText.yy_lineSpacing = lineSpace ?? 4

        let range = contentText.string.range(of: packupStr)
        
        let textHighlight = YYTextHighlight()

        contentText.yy_setTextHighlight(textHighlight, range: contentText.string.nsRange(from: range!))

        textHighlight.tapAction = { [weak self] (_: UIView, _: NSAttributedString, _: NSRange, _: CGRect) -> Void in

            self?.frame.size.height = self?.zoomHeight ?? 80

            self?.addMoreButtonToLabel()

            self?.actionClick!(false)
        }

        self.attributedText = contentText
    }
}

public extension YYLabel {
    func textHeightCalculation(maxWidth: CGFloat, lineSpacing: CGFloat) -> (CGFloat) {
        let attributedStr = NSMutableAttributedString(attributedString: NSMutableAttributedString(string: text!))
        attributedStr.yy_font = font
        attributedStr.yy_lineSpacing = lineSpacing //+ 2
        let layout = YYTextLayout(containerSize: CGSize(width: maxWidth, height: CGFloat(MAXFLOAT)), text: attributedStr)!
        return layout.textBoundingSize.height
    }
}

extension String {
    /// range转换为NSRange
    func nsRange(from range: Range<String.Index>) -> NSRange {
        return NSRange(range, in: self)
    }
}
